/*
 * @lc app=leetcode.cn id=2166 lang=typescript
 *
 * [2166] 设计位集
 */

// @lc code=start
interface Bits {
  // 第几组
  x: number;
  // 第几位
  y: number;
}

class Bitset {
  // 基数，每组保存30个二进制位
  base: number = 30;
  // 1的个数
  ones: number = 0;
  data: number[];
  n: number;
  size: number;
  constructor(size: number) {
    this.size = size;
    // 可以分多少组
    this.n = Math.ceil(size / this.base);
    this.data = new Array(this.n).fill(0);
  }

  private _getBits(idx: number): Bits {
    return {
      x: Math.floor(idx / this.base),
      y: idx % this.base,
    };
  }

  fix(idx: number): void {
    const { x, y } = this._getBits(idx);
    if ((this.data[x] & (1 << y)) == 0) {
      this.ones++;
      this.data[x] |= 1 << y;
    }
  }

  unfix(idx: number): void {
    const { x, y } = this._getBits(idx);
    if ((this.data[x] & (1 << y)) != 0) {
      this.ones--;
      this.data[x] ^= 1 << y;
    }
  }

  flip(): void {
    for (let i = 0; i < this.n; i++) {
      this.data[i] = ~this.data[i];
    }
    this.ones = this.size - this.ones;
  }

  all(): boolean {
    return this.ones === this.size;
  }

  one(): boolean {
    return this.ones > 0;
  }

  count(): number {
    return this.ones;
  }

  toString(): string {
    let m = (this.size / this.base) >> 0;
    let rest = this.size % this.base;
    let str = '';
    for (let i = 0; i < m; i++) {
      for (let j = 0; j < this.base; j++) {
        str += this.data[i] & (1 << j) ? '1' : '0';
      }
    }
    for (let j = 0; j < rest; j++) {
      str += this.data[this.n - 1] & (1 << j) ? '1' : '0';
    }

    return str;
  }
}

/**
 * Your Bitset object will be instantiated and called as such:
 * var obj = new Bitset(size)
 * obj.fix(idx)
 * obj.unfix(idx)
 * obj.flip()
 * var param_4 = obj.all()
 * var param_5 = obj.one()
 * var param_6 = obj.count()
 * var param_7 = obj.toString()
 */
// @lc code=end
